نظرة عميقة على واجهة Temporal API في JavaScript لتحويل التقاويم، مما يتيح تعيينًا دقيقًا للتواريخ عبر أنظمة تقويم متنوعة. تعلم كيفية التعامل مع التواريخ في التقويم الإسلامي والعبري والبوذي وغيرها.
تحويل التقاويم باستخدام Temporal في JavaScript: إتقان تعيين التواريخ عبر التقاويم المختلفة
يعمل العالم على أكثر من مجرد التقويم الغريغوري. تحتاج الشركات التي تتوسع عالميًا إلى مراعاة مختلف المناسبات الثقافية والدينية، والتي يرتبط كل منها بأنظمة تقويم محددة. توفر واجهة Temporal API الحديثة في JavaScript أدوات قوية للتعامل مع هذه التعقيدات، مما يسمح للمطورين بتعيين التواريخ بسلاسة بين التقاويم وضمان دقة الجدولة والحسابات وعرض البيانات. يستكشف هذا الدليل الشامل إمكانيات تحويل التقويم في واجهة Temporal API، ويقدم أمثلة عملية وأفضل الممارسات لبناء تطبيقات عالمية واعية.
فهم الحاجة إلى تعيين التواريخ عبر التقاويم المختلفة
تواجه كائنات `Date` التقليدية في JavaScript قيودًا في التعامل مع التقويمات غير الغريغورية. تعالج واجهة Temporal API هذه المشكلة من خلال توفير طريقة موحدة وقوية للعمل مع أنظمة التقويم المختلفة. خذ بعين الاعتبار هذه السيناريوهات:
- جدولة الاجتماعات الدولية: يعد التحديد الدقيق للتاريخ المكافئ في التقويم الإسلامي (الهجري) أو العبري لحدث مجدول بالتقويم الغريغوري أمرًا بالغ الأهمية لاحترام الأعياد الدينية والحساسيات الثقافية.
- حساب فوائد القروض في مناطق مختلفة: تستخدم بعض المؤسسات المالية تقاويم محددة لحسابات الفائدة. تسمح واجهة Temporal بإجراء عمليات حسابية دقيقة على التواريخ في هذه الأنظمة.
- عرض التواريخ بالتنسيقات المفضلة للمستخدم: يؤدي تخصيص عرض التواريخ وفقًا لإعدادات المستخدم المحلية وتفضيلاته التقويمية إلى تحسين تجربة المستخدم، خاصة للتطبيقات التي تستهدف جماهير متنوعة.
- تحليل البيانات التاريخية: عند العمل مع مجموعات البيانات التاريخية، يصبح فهم وتحويل التواريخ المسجلة في تقاويم أقدم أو أقل شيوعًا أمرًا ضروريًا للتفسير الدقيق.
مقدمة عن واجهة Temporal API والتقاويم
تقدم واجهة Temporal API، المدعومة الآن على نطاق واسع في بيئات JavaScript الحديثة، طريقة أكثر بديهية وقوة للعمل مع التواريخ والأوقات والمناطق الزمنية. في جوهرها، يمثل كائن `Temporal.Calendar` نظامًا تقويميًا محددًا. يمكن ربط Temporal.PlainDate و Temporal.PlainDateTime وأنواع Temporal الأخرى بمثيل `Temporal.Calendar`.
تدعم واجهة Temporal API حاليًا التقاويم التالية (في وقت كتابة هذا التقرير):
- `iso8601` (الغريغوري - الافتراضي)
- `gregory` (مرادف لـ `iso8601`)
- `islamic` (إسلامي)
- `islamic-umalqura` (إسلامي - أم القرى)
- `islamic-tbla` (إسلامي - جدولي)
- `islamic-rgsa` (إسلامي - الأمانة العامة الدينية للأوقاف المصرية)
- `islamic-civil` (إسلامي - مدني)
- `hebrew` (عبري)
- `buddhist` (بوذي)
- `roc` (جمهورية الصين)
- `japanese` (ياباني)
- `persian` (فارسي)
قد تقدم الإصدارات المستقبلية المزيد من التقاويم أو تسمح بتنفيذ تقاويم مخصصة.
التحويل الأساسي للتقاويم باستخدام Temporal.PlainDate
يمثل كائن `Temporal.PlainDate` تاريخًا بدون منطقة زمنية. يمكنك إنشاء `Temporal.PlainDate` مرتبط بتقويم معين:
const gregorianDate = Temporal.PlainDate.from('2024-01-20');
const islamicCalendar = Temporal.Calendar.from('islamic');
const islamicDate = Temporal.PlainDate.from({ year: 1445, month: 6, day: 8, calendar: islamicCalendar });
console.log(gregorianDate.toString()); // المخرجات: 2024-01-20
console.log(islamicDate.toString()); // المخرجات: 1445-06-08[u-ca=islamic]
ستقوم دالة `toString()` بإخراج التاريخ مع تعليق توضيحي للتقويم `[u-ca=islamic]`. يشير هذا إلى أن التاريخ مرتبط بالتقويم الإسلامي.
التحويل بين التقاويم
يكمن مفتاح التحويل بين التقاويم في إنشاء كائنات `Temporal.PlainDate` مرتبطة بكل تقويم ثم استخراج مكونات التاريخ الخاصة بكل منها. إليك كيفية تحويل تاريخ غريغوري إلى ما يعادله في التقويم الإسلامي:
const gregorianDate = Temporal.PlainDate.from('2024-01-20');
const islamicCalendar = Temporal.Calendar.from('islamic');
// استخراج مكونات التاريخ في التقويم الإسلامي
const islamicYear = gregorianDate.toPlainDate(islamicCalendar).year;
const islamicMonth = gregorianDate.toPlainDate(islamicCalendar).month;
const islamicDay = gregorianDate.toPlainDate(islamicCalendar).day;
console.log(`Gregorian: ${gregorianDate.toString()}`);
console.log(`Islamic: ${islamicYear}-${islamicMonth}-${islamicDay}`); // المخرجات: Islamic: 1445-6-8
دعنا نحلل هذا المثال:
- نبدأ بـ `gregorianDate` ممثلاً ككائن `Temporal.PlainDate`.
- نقوم بإنشاء كائن `islamicCalendar` باستخدام `Temporal.Calendar.from('islamic')`.
- يحدث التحويل الأساسي باستخدام `gregorianDate.toPlainDate(islamicCalendar)`. يؤدي هذا إلى إنشاء كائن `Temporal.PlainDate` جديد يمثل نفس النقطة الزمنية، ولكنه مرتبط الآن بالتقويم الإسلامي.
- نستخرج مكونات `year` و `month` و `day` من كائن `Temporal.PlainDate` المحول.
يمكنك تكييف هذا النمط للتحويل بين أي تقويمين تدعمهما واجهة Temporal API.
التعامل المتقدم مع التقويم: التقويم الإسلامي
يحتوي التقويم الإسلامي على عدة أشكال. تدعم واجهة Temporal API هذه الأشكال:
- `islamic`: تقويم إسلامي عام (قد يختلف التنفيذ).
- `islamic-umalqura`: يعتمد على تقويم أم القرى في المملكة العربية السعودية.
- `islamic-tbla`: يعتمد على الحساب الجدولي.
- `islamic-rgsa`: يعتمد على الأمانة العامة الدينية للأوقاف (مصر).
- `islamic-civil`: نسخة حسابية بحتة من التقويم الإسلامي، تستخدم بشكل أساسي في الحسابات.
عند العمل مع التقويم الإسلامي، من الضروري فهم أي شكل هو الأنسب لحالة الاستخدام الخاصة بك. على سبيل المثال، للمناسبات الدينية في المملكة العربية السعودية، من المحتمل أن ترغب في استخدام `islamic-umalqura`. بالنسبة للحسابات المالية، قد يكون `islamic-civil` أكثر ملاءمة بسبب طبيعته القابلة للتنبؤ.
const gregorianDate = Temporal.PlainDate.from('2024-03-11');
const islamicUmalquraCalendar = Temporal.Calendar.from('islamic-umalqura');
const islamicCivilCalendar = Temporal.Calendar.from('islamic-civil');
const islamicUmalquraDate = gregorianDate.toPlainDate(islamicUmalquraCalendar);
const islamicCivilDate = gregorianDate.toPlainDate(islamicCivilCalendar);
console.log(`Gregorian: ${gregorianDate.toString()}`);
console.log(`Islamic (Umm al-Qura): ${islamicUmalquraDate.year}-${islamicUmalquraDate.month}-${islamicUmalquraDate.day}`);
console.log(`Islamic (Civil): ${islamicCivilDate.year}-${islamicCivilDate.month}-${islamicCivilDate.day}`);
اعتبارات هامة للتقويم الإسلامي:
- تعتمد بداية شهر جديد في التقويم الإسلامي على رؤية هلال القمر الجديد. يهدف تقويم `islamic-umalqura` إلى التوافق مع الرؤية الفعلية للقمر في المملكة العربية السعودية، ولكن لا يزال من الممكن حدوث اختلافات.
- يعتبر تقويم `islamic-civil` تقريبًا رياضيًا ولا يعكس الرؤية الفعلية للقمر.
- استشر دائمًا السلطات الدينية المختصة أو المصادر الموثوقة للحصول على تواريخ دقيقة للأعياد الإسلامية.
العمل مع التقويم العبري
التقويم العبري هو تقويم شمسي قمري يستخدم للمناسبات الدينية اليهودية وكتقويم رسمي في إسرائيل. يتضمن أشهرًا كبيسة للحفاظ على توافقه مع الفصول.
const gregorianDate = Temporal.PlainDate.from('2024-03-11');
const hebrewCalendar = Temporal.Calendar.from('hebrew');
const hebrewDate = gregorianDate.toPlainDate(hebrewCalendar);
console.log(`Gregorian: ${gregorianDate.toString()}`);
console.log(`Hebrew: ${hebrewDate.year}-${hebrewDate.month}-${hebrewDate.day}`);
الميزات الرئيسية للتقويم العبري و Temporal:
- تتم معالجة الأشهر الكبيسة تلقائيًا بواسطة واجهة Temporal API. لا تحتاج إلى تنفيذ منطق مخصص لتحديد السنوات الكبيسة أو إضافة أشهر إضافية.
- يبدأ ترقيم السنوات من الحقبة اليهودية التقليدية (خلق العالم).
- تختلف أسماء أشهر التقويم العبري عن التقويم الغريغوري. يمكنك الوصول إلى أسماء هذه الأشهر من خلال مكتبات التدويل (i18n) أو التعيينات المخصصة.
التعامل مع التقاويم البوذية، وجمهورية الصين، واليابانية، والفارسية
تدعم واجهة Temporal API تقاويم أخرى أيضًا، لكل منها خصوصياته. إليك بعض الاعتبارات:
- التقويم البوذي: التقويم البوذي هو تقويم شمسي قمري يستخدم في العديد من دول جنوب شرق آسيا. يبدأ ترقيم السنوات عادةً من وفاة بوذا.
- تقويم جمهورية الصين (ROC): يستخدم هذا التقويم في تايوان ويُرقم السنوات بدءًا من تأسيس جمهورية الصين في عام 1912.
- التقويم الياباني: يعتمد التقويم الياباني على التقويم الغريغوري ولكنه يستخدم أسماء العصور اليابانية (nengō) للإشارة إلى السنوات.
- التقويم الفارسي: التقويم الفارسي هو تقويم شمسي يستخدم بشكل أساسي في إيران وأفغانستان.
const gregorianDate = Temporal.PlainDate.from('2024-03-11');
const buddhistCalendar = Temporal.Calendar.from('buddhist');
const rocCalendar = Temporal.Calendar.from('roc');
const japaneseCalendar = Temporal.Calendar.from('japanese');
const persianCalendar = Temporal.Calendar.from('persian');
const buddhistDate = gregorianDate.toPlainDate(buddhistCalendar);
const rocDate = gregorianDate.toPlainDate(rocCalendar);
const japaneseDate = gregorianDate.toPlainDate(japaneseCalendar);
const persianDate = gregorianDate.toPlainDate(persianCalendar);
console.log(`Gregorian: ${gregorianDate.toString()}`);
console.log(`Buddhist: ${buddhistDate.year}-${buddhistDate.month}-${buddhistDate.day}`);
console.log(`ROC: ${rocDate.year}-${rocDate.month}-${rocDate.day}`);
console.log(`Japanese: ${japaneseDate.year}-${japaneseDate.month}-${japaneseDate.day}`);
console.log(`Persian: ${persianDate.year}-${persianDate.month}-${persianDate.day}`);
عند استخدام هذه التقاويم، كن على دراية بحقبتها المحددة (سنة البداية) وأي فروق ثقافية دقيقة مرتبطة بتمثيل التاريخ.
Temporal.Now واعتبارات التقويم
بينما يمكن استخدام `Temporal.Now` للحصول على التاريخ والوقت الحاليين، من المهم أن نفهم أنها تُرجع التاريخ والوقت الحاليين في تقويم ISO 8601 بشكل افتراضي. إذا كنت بحاجة إلى التاريخ الحالي في تقويم مختلف، فستحتاج إلى تحويله:
const islamicCalendar = Temporal.Calendar.from('islamic');
const now = Temporal.Now.plainDateISO(); // التاريخ الحالي في تقويم ISO 8601
const islamicNow = now.toPlainDate(islamicCalendar);
console.log(`Current Gregorian Date: ${now.toString()}`);
console.log(`Current Islamic Date: ${islamicNow.year}-${islamicNow.month}-${islamicNow.day}`);
تنسيق التواريخ والتدويل (i18n)
تحويل التواريخ هو جزء فقط من المعادلة. تحتاج أيضًا إلى تنسيقها بشكل صحيح للعرض. توفر واجهة `Intl.DateTimeFormat` في JavaScript إمكانيات تدويل قوية. يمكنك استخدامها بالاقتران مع واجهة Temporal API لتنسيق التواريخ بطريقة واعية باللغة المحلية، مع مراعاة التقويم المرتبط.
const gregorianDate = Temporal.PlainDate.from('2024-01-20');
const islamicCalendar = Temporal.Calendar.from('islamic');
const islamicDate = gregorianDate.toPlainDate(islamicCalendar);
const formatter = new Intl.DateTimeFormat('ar-SA-u-ca-islamic', { // العربية (المملكة العربية السعودية) مع التقويم الإسلامي
year: 'numeric',
month: 'long',
day: 'numeric',
});
console.log(formatter.format(islamicDate)); // مثال على المخرجات: ٢٠ رجب، ١٤٤٥ هـ
لنحلل الكود:
- `'ar-SA-u-ca-islamic'` هي سلسلة اللغة المحلية. تحدد `ar-SA` اللغة العربية (المملكة العربية السعودية)، و `u-ca-islamic` تطلب صراحةً التقويم الإسلامي.
- تتحكم خيارات `Intl.DateTimeFormat` في كيفية تنسيق التاريخ (السنة، الشهر، اليوم).
- تأخذ دالة `format()` كائن `Temporal.PlainDate` (في هذه الحالة، `islamicDate`) وتُرجع سلسلة منسقة وفقًا للغة المحلية والتقويم المحددين.
يمكنك تكييف سلسلة اللغة المحلية وخيارات التنسيق لتناسب احتياجاتك الخاصة. على سبيل المثال، لتنسيق التاريخ باللغة العبرية:
const gregorianDate = Temporal.PlainDate.from('2024-03-11');
const hebrewCalendar = Temporal.Calendar.from('hebrew');
const hebrewDate = gregorianDate.toPlainDate(hebrewCalendar);
const formatter = new Intl.DateTimeFormat('he-IL-u-ca-hebrew', { // العبرية (إسرائيل) مع التقويم العبري
year: 'numeric',
month: 'long',
day: 'numeric',
});
console.log(formatter.format(hebrewDate));
نصائح لتنسيق فعال للتاريخ:
- استخدم سلاسل لغة محلية تعكس بدقة اللغة والمنطقة المفضلة للمستخدم.
- اختر خيارات تنسيق مناسبة للسياق (على سبيل المثال، تنسيقات تاريخ قصيرة للعروض المدمجة، وتنسيقات تاريخ طويلة للعروض التفصيلية).
- اختبر التنسيق الخاص بك عبر لغات محلية مختلفة لضمان الدقة وسهولة القراءة.
إجراء العمليات الحسابية على التواريخ عبر التقاويم
تتفوق واجهة Temporal API في العمليات الحسابية على التواريخ. يمكنك إضافة أو طرح أيام أو أشهر أو سنوات من كائن `Temporal.PlainDate`، حتى عند العمل مع تقاويم غير غريغورية.
const gregorianDate = Temporal.PlainDate.from('2024-01-20');
const islamicCalendar = Temporal.Calendar.from('islamic');
const islamicDate = gregorianDate.toPlainDate(islamicCalendar);
// إضافة 30 يومًا إلى التاريخ الإسلامي
const futureIslamicDate = islamicDate.add({ days: 30 });
console.log(`Original Islamic Date: ${islamicDate.year}-${islamicDate.month}-${islamicDate.day}`);
console.log(`Islamic Date + 30 days: ${futureIslamicDate.year}-${futureIslamicDate.month}-${futureIslamicDate.day}`);
// تحويل التاريخ الإسلامي المستقبلي مرة أخرى إلى الغريغوري
const futureGregorianDate = futureIslamicDate.toPlainDate('iso8601');
console.log(`Equivalent Gregorian Date: ${futureGregorianDate.toString()}`);
اعتبارات رئيسية للعمليات الحسابية على التواريخ:
- تُرجع دالتا `add()` و `subtract()` كائنات `Temporal.PlainDate` جديدة؛ لا تقومان بتعديل الكائن الأصلي.
- عند إضافة أو طرح أشهر أو سنوات، تتعامل واجهة Temporal API مع القواعد الخاصة بالتقويم للسنوات الكبيسة وأطوال الأشهر.
- كن حذرًا من التجاوزات المحتملة للتواريخ عند إجراء العمليات الحسابية. ستقوم واجهة Temporal API عادةً بضبط التاريخ إلى أقرب تاريخ صالح ضمن التقويم.
التعامل مع التواريخ الغامضة
في بعض الحالات، قد يكون التاريخ غامضًا عند التحويل بين التقاويم. يمكن أن يحدث هذا عندما لا يوجد تاريخ معين في التقويم الهدف أو عندما يمكن أن تتوافق تواريخ متعددة في التقويم الهدف مع تاريخ المصدر. تتعامل Temporal مع هذه المواقف برشاقة، عادةً عن طريق إرجاع أقرب تاريخ صالح.
على سبيل المثال، ضع في اعتبارك تحويل تاريخ غريغوري قريب من نهاية شهر غريغوري إلى التقويم الإسلامي، حيث قد يكون الشهر الإسلامي المقابل أقصر. ستقوم Temporal تلقائيًا بضبط التاريخ الإسلامي الناتج إلى آخر يوم في ذلك الشهر.
معالجة الأخطاء والتحقق من الصحة
على الرغم من أن واجهة Temporal API قوية، فمن الضروري تنفيذ معالجة أخطاء وتحقق من الصحة بشكل صحيح لمنع السلوك غير المتوقع. إليك بعض السيناريوهات الشائعة التي يجب مراعاتها:
- أسماء تقويم غير صالحة: إذا قمت بتقديم اسم تقويم غير صالح إلى `Temporal.Calendar.from()`، فسيؤدي ذلك إلى إطلاق `RangeError`. التقط هذا الخطأ وقدم رسالة سهلة الاستخدام.
- تنسيقات تاريخ غير صالحة: إذا حاولت إنشاء `Temporal.PlainDate` من سلسلة تاريخ غير صالحة، فسيؤدي ذلك إلى إطلاق `RangeError`. تحقق من صحة سلاسل التاريخ قبل تمريرها إلى `Temporal.PlainDate.from()`.
- عمليات غير مدعومة: قد لا تكون بعض العمليات الخاصة بالتقويم مدعومة من قبل واجهة Temporal API. تحقق من الوثائق الخاصة بالتقويم المحدد الذي تستخدمه.
أفضل الممارسات لتعيين التواريخ عبر التقاويم
لضمان الدقة والقابلية للصيانة عند العمل مع تعيين التواريخ عبر التقاويم، اتبع هذه الممارسات الأفضل:
- استخدم واجهة Temporal API: توفر واجهة Temporal API طريقة موحدة وقوية للتعامل مع تحويلات التقويم. تجنب استخدام كائنات `Date` القديمة في JavaScript لهذا الغرض.
- حدد التقاويم بشكل صريح: حدد دائمًا التقويم بشكل صريح عند إنشاء كائنات `Temporal.PlainDate`. هذا يمنع الغموض ويضمن تطبيق القواعد التقويمية الصحيحة.
- اختر الشكل الصحيح للتقويم الإسلامي: افهم الاختلافات بين تطبيقات التقويم الإسلامي المختلفة واختر الأنسب لحالة الاستخدام الخاصة بك.
- استخدم التدويل (i18n): استفد من واجهة `Intl.DateTimeFormat` لتنسيق التواريخ بطريقة واعية باللغة المحلية.
- نفذ معالجة الأخطاء: نفذ معالجة أخطاء قوية لالتقاط أسماء التقويم غير الصالحة، وتنسيقات التاريخ، والمشكلات المحتملة الأخرى.
- اختبر بدقة: اختبر الكود الخاص بك مع مجموعة متنوعة من التواريخ واللغات المحلية لضمان الدقة والتوافق.
- ابق على اطلاع: لا تزال واجهة Temporal API في تطور مستمر. ابق على اطلاع بأحدث المواصفات وتطبيقات المتصفحات.
الخاتمة
تُحدث واجهة Temporal API في JavaScript ثورة في كيفية تعاملنا مع التواريخ والتقاويم، حيث توفر طريقة قوية وموحدة لإجراء تعيين التواريخ عبر التقاويم المختلفة. من خلال فهم الفروق الدقيقة في أنظمة التقويم المختلفة واستخدام واجهة Temporal API بفعالية، يمكن للمطورين بناء تطبيقات عالمية واعية تلبي الاحتياجات الثقافية والدينية المتنوعة. احتضن واجهة Temporal API لإنشاء حلول معالجة تواريخ أكثر شمولاً ودقة في مشاريعك.
قدم هذا الدليل نظرة عامة شاملة على تحويل التقويم باستخدام واجهة JavaScript Temporal API. تذكر الرجوع إلى وثائق Temporal API الرسمية للحصول على أحدث المعلومات والمواصفات التفصيلية.